/**
 * 最长递增子序列 单个节点
 * data:[] ,get [deepth]
 */
class longestChildTreeDom {
  get [Symbol.toStringTag]() {
    return 'longestChildTree';
  }
  constructor() {
    this['data'] = [];
    this['name'] = '';
  }

  get deepth() {
    let largestDeepth = 0;
    let data = this.data;
    if (data.length > 0) {
      for (let i = 0; i < data.length; i++) {
        // console.log(this[data[i]].deepth);
        largestDeepth =
          this[data[i]].deepth + 1 > largestDeepth
            ? this[data[i]].deepth + 1
            : largestDeepth;
      }
    }
    return largestDeepth;
  }
}

/**
 * --O(2^n) 过于复杂
 * @param {Array} numArr -- 数字数组
 * @returns
 */
function longestChildArr(numArr) {
  let count = 0;
  //   console.log(numArr);
  if (!IsNumArr(numArr)) {
    console.log('sorry your sequence is not a Number Array');
    return;
  }

  /**
   * 庄严树
   */
  let venerableTree = new longestChildTreeDom();

  /**
   * current Dom --当前节点
   */
  let aTree;

  //内部 关键 分割线
  let splitPart = '_';

  let length = numArr.length;

  let remind;

  //deep 深度节点 arr
  let DeepthArr;

  //根据 深度 生成庄严树
  function treeShake(deep) {
    //单点 确认是否 有 更大的值
    let alowedDeeper = false;
    let deepInit = false;

    //获取 同级 深度 的节点
    let promisedIndexArr = getDeepthIndexArr(deep);
    if (deep == 0) {
      deepInit = true;
    }

    //一级循环 同深度 节点 序号
    for (let i = 0; i < promisedIndexArr.length; i++) {
      let deepthLastIndex = numArr.indexOf(
        Number(promisedIndexArr[i][promisedIndexArr[i].length - 1])
      );
      //   console.log(
      //     promisedIndexArr[i][promisedIndexArr[i].length - 1],
      //     deepthLastIndex
      //   );
      if (deepthLastIndex == -1) {
        deepthLastIndex = 0;
      }
      //二级循环 节点后的 数据
      for (let j = deepthLastIndex; j < length; j++) {
        count++;
        //节点 有 比 一级循环 大 的 数据 进行深度记录
        if (numArr[deepthLastIndex] < numArr[j] || deepInit) {
          //将 aTree 定位 到 指定 位置
          todeepDom(promisedIndexArr[i]);

          //装载 信息
          settleKeyNode(j);

          //确认 有新增节点
          alowedDeeper = true;
        }
      }
    }
    if (alowedDeeper) {
      treeShake(++deep);
    }
  }

  /**
   * 根据 序号 数组 定位尊严树 中的某个节点 并返回 该节点
   * @param {Array} deepthArr 定位节点 的 数组
   * @returns
   */
  function todeepDom(deepthArr) {
    aTree = venerableTree;
    for (let i = 0; i < deepthArr.length; i++) {
      if (aTree['data'].indexOf(Number(deepthArr[i])) == -1) {
        return aTree;
      }
      aTree = aTree[deepthArr[i]];
    }
    return aTree;
  }

  /**
   * 根据 节点的 Name 返回 序号数组
   * @param {String} name --节点 Name
   * @returns
   */
  function asyncNameDeepth(name) {
    return name.split(splitPart);
  }

  /**
   * 当前节点 添加 新创建的 dom 到 atree 中
   * @param {Number} key  序号
   */
  function settleKeyNode(keyIndex) {
    let key = numArr[keyIndex];
    let preDeep = aTree['name'];

    //新开辟 一个节点
    remind = new longestChildTreeDom();

    let currentDeep = preDeep == '' ? `${key}` : `${preDeep}${splitPart}${key}`;

    if (aTree['data'].indexOf(key) == -1) {
      aTree['data'].push(key);
      aTree[key] = remind;

      remind.name = currentDeep;
    }
  }

  /**
   * 根据深度 返回可能符合条件的 数字序列
   * @param {Number} deepth  深度
   * @returns [[],[]]
   */
  function getDeepthIndexArr(deepth) {
    DeepthArr = [];

    if (deepth == 0) {
      return [[NaN]];
    } else {
      virtualDomSearch(venerableTree, deepth);
    }
    return DeepthArr;
  }

  /**
   * 跟进 节点 获取 对应深度 叶节点
   * @param {longestChildTreeDom} virtualDom 当前递归节点
   * @param {Number} deep2 深度
   */
  function virtualDomSearch(virtualDom, deep2) {
    for (let i = 0; i < virtualDom['data'].length; i++) {
      const el = virtualDom['data'][i];
      if (virtualDom[el].deepth == 0 && deep2 == 1) {
        DeepthArr.push(asyncNameDeepth(virtualDom[el].name));
      } else if (deep2 > 1) {
        virtualDomSearch(virtualDom[el], deep2 - 1);
      }
    }
  }

  /**
   * 给到 最深 节点 或 最深节点 数组
   * @returns
   */
  function getLongestSque() {
    let domD;
    DeepthArr = [];

    virtualDomSearch(venerableTree, venerableTree.deepth);
    if (DeepthArr.length > 1) {
      domD = {};
      domD['length'] = DeepthArr.length;
      //   console.log(DeepthArr);
      for (let i = 0; i < DeepthArr.length; i++) {
        domD[i] = todeepDom(DeepthArr[i]);
      }
    } else {
      //   console.log(DeepthArr);
      domD = todeepDom(DeepthArr[0]);
    }

    return domD;
  }

  treeShake(0);
  //   console.log(venerableTree);
  console.log('count:', count);
  return { longestdom: getLongestSque(), venerableTree };
}

function IsNumArr(numArr) {
  let bool = true;

  let reNum = /^-?\d+(\.\d+)?$/;

  for (let i = 0; i < numArr.length; i++) {
    if (!reNum.test(numArr[i])) {
      bool = false;
    }
  }
  return bool;
}

//2023.09.01 21：57 晴 写完了 要是需要 进行返回值操作 直接改就好 今天 不太想看 吕游 没意思
export { longestChildArr };
